package utils;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;

import bean.Behaviour;
import bean.PEWSOperation;
import bean.PEWSOperations;
import bean.PortType;
import bean.WSDLOperation;

/**
 * Classe que insere os objetos "PEWSOperation" e "WSDLOperation" em suas respectivas hashs, e os compara
 * 
 */

public class Comparador {
	private Hashtable<Integer, PEWSOperation> hstXPEWS;
	private Hashtable<String, WSDLOperation> hstWSDL;
	private Hashtable<String, String> hstBehaviour;
	private int con = 0;
	
	public Comparador(){
		hstXPEWS = new Hashtable<Integer, PEWSOperation>();
		hstWSDL = new Hashtable<String, WSDLOperation>();
		hstBehaviour = new Hashtable<String, String>();
	}
	
	/** Insere o objeto "PEWSOperation" de um XPEWS na hash, de forma que:
	 *  Chave - Contador inteiro incremental 
	 *  Valor - O objeto "PEWSOperation"  */
	public void inserirXPEWSNaHash(PEWSOperations pewsOps){
		for(int i = 0; i < pewsOps.getPewsOperations().size(); i++)
			hstXPEWS.put(con++, pewsOps.getPewsOperations().get(i));
	}
	
	/** Insere o objeto "WSDLOperation" de um WSDL na hash, de forma que:
	 *  Chave - Nome da Operation
	 *  Valor - O objeto "WSDLOperation"  */
	public void inserirWSDLNaHash(PortType portType){
		for(int i = 0; i < portType.getOperations().size(); i++)
			hstWSDL.put(portType.getOperations().get(i).getName(), portType.getOperations().get(i));
	}
	
	/** Insere um NameSpace e seu respectivo link na hash, de forma que:
	 *  Chave - NameSpace
	 *  Valor - Link NameSpace  */
	public void inserirBehaviourNaHash(Behaviour behaviour){
		for(int i = 0; i < behaviour.getNs().size(); i++)
			hstBehaviour.put(behaviour.getNs().get(i), behaviour.getLinkNs().get(i));
	}
	
	/** Compara a hash do WSDL - "hstWSDL" - com a hash XPEWS - "hstXPEWS" -,
	 *  e retorna um ArrayList com os métodos em comum */
	private ArrayList<String> compararTodos(){
		ArrayList<String> operationsEmComum = new ArrayList<String>();
		
		for(PEWSOperation xpews : hstXPEWS.values()){
			if(hstWSDL.containsKey(xpews.getName()))
				operationsEmComum.add(xpews.getName());
		}
		
		return operationsEmComum;
	}
	
	/** Compara a hash do WSDL - "hstWSDL" - com a hash XPEWS - "hstXPEWS" -,
	 *  e retorna um ArrayList com todos os métodos com um "OK" ou "NO" após o nome da operation*/
	public ArrayList<String> compararTodosEFormatar(){
		ArrayList<String> operationsEmComum = listarOperationsXPEWSEFormatar();
		ArrayList<String> operationsOk = compararTodos();
		
		for(int i = 0; i < operationsEmComum.size(); i++){
			if(i < operationsOk.size() && hstWSDL.containsKey(operationsOk.get(i)))
				operationsEmComum.set(operationsEmComum.indexOf("    " + operationsOk.get(i)), "    " + operationsOk.get(i) + " ");
			if(!operationsEmComum.get(i).endsWith(" ") && !operationsEmComum.get(i).startsWith("ns"))
				operationsEmComum.set(i, operationsEmComum.get(i) + "  ");
		}
		
		return operationsEmComum;
	}
	
	/** Compara a hash do WSDL - "hstWSDL" - com a hash XPEWS - "hstXPEWS" -,
	 *  e retorna um ArrayList com os métodos em comum */
	public ArrayList<String> comparar(String operation){
		ArrayList<String> operationsEmComum = listarOperationsXPEWSEFormatar();
		
		if((operation.length() - operation.trim().length()) == 5)
			operation = operation.substring(0, operation.length() - 1);
		else if((operation.length() - operation.trim().length()) == 6)
			operation = operation.substring(0, operation.length() - 2);
		
		if(hstWSDL.containsKey(operation.trim()))
			operationsEmComum.set(operationsEmComum.indexOf(operation), operation + " ");
		else
			operationsEmComum.set(operationsEmComum.indexOf(operation), operation + "  ");
		
		return operationsEmComum;
	}
	
	/** Compara a hash do WSDL - "hstWSDL" - com a hash XPEWS - "hstXPEWS" -,
	 *  e retorna um ArrayList com os métodos em comum */
	public ArrayList<String> compararPorNs(String ns){
		ArrayList<String> operationsNs = new ArrayList<String>();
		ArrayList<String> operations = listarOperationsXPEWSEFormatar();
		
		for(PEWSOperation xpews : hstXPEWS.values()){
			if(ns.compareToIgnoreCase(xpews.getNs()) == 0)
				operationsNs.add(xpews.getName());
		}
		
		for(String operation : operationsNs){
			if(hstWSDL.containsKey(operation))
				operations.set(operations.indexOf("    " + operation), "    " + operation + " ");
			else 
				operations.set(operations.indexOf("    " + operation), "    " + operation + "  ");
		}
		
		return operations;
	}
	
	/** Lista o nome das operations dentro da hash "hstXPEWS" */
	public ArrayList<String> listarOperationsXPEWS(){
		ArrayList<String> operations = new ArrayList<String>();
		
		for(PEWSOperation xpews : hstXPEWS.values())
			operations.add(xpews.getName());
		
		return operations;
	}
	
	/** Lista o NameSpace e suas respectivas operations dentro das hash "hstBehaviour" e "hstXPEWS" */
	public ArrayList<String> listarOperationsXPEWSEFormatar(){
		ArrayList<String> operations = new ArrayList<String>();
		
		for(Enumeration<String> nss = hstBehaviour.keys(); nss.hasMoreElements();){
			String ns = nss.nextElement();
			operations.add(ns);
			for(PEWSOperation xpews : hstXPEWS.values()){
				if(xpews.getNs().compareToIgnoreCase(ns) == 0)
					operations.add("    " + xpews.getName());
			}
		}
		
		return operations;
	}
	
	/** Lista o nome das operations dentro da hash "hstWSDL" */
	public ArrayList<String> listarOperationsWSDL(){
		ArrayList<String> operations = new ArrayList<String>();
		
		for(WSDLOperation wsdl : hstWSDL.values())
			operations.add(wsdl.getName());
		
		return operations;
	}
	
	/** Lista os links dentro da hash "hstBehaviour" */
	public ArrayList<String> listarLinksNsBehaviour(){
		ArrayList<String> linksNs = new ArrayList<String>();
		
		for(String ns : hstBehaviour.values())
			linksNs.add(ns);

		return linksNs;
	}
	
	/** Lista os NameSpaces dentro da hash "hstBehaviour" */
	public ArrayList<String> listarNssBehaviour(){
		ArrayList<String> nss = new ArrayList<String>();
		
		for(Enumeration<String> ns = hstBehaviour.keys(); ns.hasMoreElements();)
			nss.add(ns.nextElement());

		return nss;
	}
	
	/** Retorna o link do WSDL da operation */
	public String retornarLinkPelaOperation(String operation){
		String ns = "";
		
		for(PEWSOperation xpews : hstXPEWS.values()){
			if(operation.compareToIgnoreCase(xpews.getName()) == 0)
				ns = xpews.getNs();
		}
		
		return hstBehaviour.get(ns);
	}

	public Hashtable<Integer, PEWSOperation> getHstXPEWS() {
		return hstXPEWS;
	}

	public void setHstXPEWS(Hashtable<Integer, PEWSOperation> hstXPEWS) {
		this.hstXPEWS = hstXPEWS;
	}
	
	public Hashtable<String, WSDLOperation> getHstWSDL() {
		return hstWSDL;
	}

	public void setHstWSDL(Hashtable<String, WSDLOperation> hstWSDL) {
		this.hstWSDL = hstWSDL;
	}

	public Hashtable<String, String> getHstBehaviour() {
		return hstBehaviour;
	}

	public void setHstBehaviour(Hashtable<String, String> hstBehaviour) {
		this.hstBehaviour = hstBehaviour;
	}
}
